home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus Leser 15 / Amiga Plus Leser CD 15.iso / Tools / Hardware / BlizKick / Modules / AlertFix.ASM < prev    next >
Encoding:
Assembly Source File  |  2002-03-13  |  9.7 KB  |  481 lines

  1. ; FILE: Source:modules/AlertFix.ASM          REV: 5 --- cool Alert fix for 040/060
  2.  
  3. ;
  4. ; AlertFix patch for BlizKick ("patch" Module)
  5. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  6. ;
  7. ; This patch fixes the problems with pending alerts & 680x0.library
  8. ; being resident in blizzppc flash. Also fixes two bugs in exec/Alert().
  9. ; If NewAlert module is installed make the exec/Alert() call it too
  10. ; (meaning that AlertFix should come after NewAlert if both are used).
  11. ;
  12. ;
  13. ; V1.1 - 2nd Feb 2000
  14. ; Fixed major bug from the code, it broke regular Alert() calls. Huh.
  15. ;
  16. ; V1.2 - 5th Feb 2000
  17. ; Made it possible to plant AlertFix inside ROM.
  18. ;
  19. ; V1.3 - 11th Sep 2000
  20. ; Now really properly disable MMU instead of 'moves' -hack. Should
  21. ; work with 68040 now, I hope. Added internal support for NewAlert
  22. ; module. Added fix for two exec/Alert() bugs. Now also patches
  23. ; '$104 = ThisTask' -write, was missing before, oops. No longer calls
  24. ; Supervisor thru execbase vector, but with direct jsr, should make
  25. ; the patch work better during serious error conditions. Now works
  26. ; with 68020 and 68030 too.
  27. ;
  28. ;
  29. ; Written by Harry "Piru" Sintonen.
  30. ; This source code is Public Domain.
  31.  
  32.     include    "blizkickmodule.i"    ; Some required...
  33.  
  34.     SECTION    PATCH,CODE
  35. _DUMMY_LABEL
  36.     BK_PTC
  37.  
  38. ; Code is run with following incoming parameters:
  39. ;
  40. ; a0=ptr to ROM start (buffer)    eg. $1DE087B8
  41. ; a1=ptr to ROM start (ROM)    eg. $00F80000 (do *not* access!)
  42. ; d0=ROM lenght in bytes    eg. $00080000
  43. ; a2=ptr to _FindResident routine (will search ROM buffer for resident tag):
  44. ;    CALL: jsr (a2)
  45. ;      IN: a0=ptr to ROM, d0=rom len, a1=ptr to resident name
  46. ;     OUT: d0=ptr to resident (buf) or NULL
  47. ; a3=ptr to _InstallModule routine (can be used to plant a "module"):
  48. ;    CALL: jsr (a3)
  49. ;      IN: a0=ptr to ROM, d0=rom len, a1=ptr to module, d6=dosbase
  50. ;     OUT: d0=success
  51. ; a4=ptr to _Printf routine (will dump some silly things (errormsg?) to stdout ;-)
  52. ;    CALL: jsr (a4)
  53. ;      IN: a0=FmtString, a1=Array (may be 0), d6=dosbase
  54. ;     OUT: -
  55. ; d6=dosbase, a6=execbase
  56. ;
  57. ; Code should return:
  58. ;
  59. ; d0=true if succeeded, false if failed.
  60. ; d1-d7/a0-a6 can be trashed. a7 *must* be preserved! ;-)
  61.  
  62.     moveq    #0,d7
  63.  
  64.     cmp.w    #37,($C,a0)        ;requires V37+ rom image
  65.     blo    .exit
  66.  
  67.     lea    (regs,pc),a5
  68.     movem.l    d0/a0-a4,(a5)
  69.  
  70.     lea    (.no020p,pc),a1
  71.     btst    #1,($128+1,a6)        AFB_68020 AttnFlags
  72.     beq    .err
  73.  
  74.     lea    (.resname,pc),a1
  75.     movem.l    (regs,pc),d0/a0
  76.     move.l    (findresident,pc),a2
  77.     jsr    (a2)
  78.     lea    (.nores,pc),a1
  79.     tst.l    d0
  80.     beq    .err
  81.  
  82.     move.l    d0,a4
  83.     moveq    #4,d2
  84.     move.l    (RT_INIT,a4),a2
  85.     add.l    a2,d2
  86.     move.l    d2,_newalert_addr
  87.     move.l    d2,_backfromh1
  88.  
  89.     ;test if inside rom bounds?
  90.     move.l    (rom_log,pc),d0
  91.     cmp.l    d0,a2
  92.     blo.b    .nofix
  93.     add.l    (rom_size,pc),d0
  94.     cmp.l    d0,a2
  95.     bhs.b    .nofix
  96.     ; inside rom, so generate ram buffer address
  97.     sub.l    (rom_log,pc),a2        -$f80000
  98.     add.l    (rom_phys,pc),a2    +buffer
  99. .nofix
  100.     moveq    #0,d3
  101.     cmp.l    #'NewA',(-4,a2)        is it our NewAlert patch?
  102.     beq.b    .na_cont        yep, special handling then
  103.  
  104.     ; check validity of the alert.hook tag
  105.     lea    (.badres,pc),a1
  106.     cmp.l    #$42B80000,(a2)
  107.     bne    .err
  108.     cmp.w    #$48E7,(4,a2)
  109.     bne    .err
  110.     cmp.w    #$242E,(8,a2)
  111.     bne    .err
  112.  
  113.     ; find 'clr.l (0).w' in alert.hook end
  114.     move.w    #1024/2,d0
  115. .find    subq.w    #1,d0
  116.     beq    .err
  117.     addq.l    #2,a2
  118.     cmp.l    #$42B80000,(a2)        'clr.l (0).w'
  119.     bne.b    .find
  120.     cmp.w    #$70FF,(4,a2)        'moveq #-1,d0'
  121.     bne.b    .find
  122.     move.l    a2,d3
  123. .na_cont
  124.  
  125.     ; find $0 and $100 accesses in Alert()
  126.     lea    (.badrom1,pc),a1
  127.     move.l    (rom_phys,pc),a2
  128.     move.w    #16384/2,d0
  129.     lea    ($2000,a2),a2
  130. .find2    subq.w    #1,d0
  131.     beq    .err
  132.     addq.l    #2,a2
  133.     cmp.l    #$203C<<16|'HE',(a2)
  134.     bne.b    .find2
  135.     cmp.l    #'LP'<<16|$B0B8,(4,a2)
  136.     bne.b    .find2
  137.     cmp.l    #$21C00000,(12,a2)
  138.     bne.b    .find2
  139.     cmp.l    #$41F80100,(16,a2)
  140.     bne.b    .find2
  141.  
  142.     ; find Alert() DisplayAlert bsr
  143.     lea    (20,a2),a0
  144.     moveq    #64,d0
  145. .find3    subq.l    #1,d0
  146.     beq    .err
  147.     addq.l    #2,a0
  148.     cmp.w    #$6100,(a0)        'bsr.w x'
  149.     bne.b    .find3
  150.     cmp.l    #$4AAE0126,(4,a0)    check for both bugged &
  151.     beq.b    .found3            bugfree 'tst.x IDNestCnt(a6)'
  152.     cmp.l    #$4A2E0126,(4,a0)
  153.     bne.b    .find3
  154. .found3    move.l    a0,d4
  155.  
  156.  
  157.     ; find VBR bug in Alert()
  158.     moveq    #64,d0
  159. .find4    subq.l    #1,d0
  160.     beq    .err
  161.     addq.l    #2,a0
  162.     cmp.l    #$21FC00F8,(a0)
  163.     bne.b    .find4
  164.     cmp.l    #$002046FC,(6,a0)
  165.     bne.b    .find4
  166.     addq.l    #8,a0
  167.     ; inside ram buffer, so generate rom address
  168.     sub.l    (rom_phys,pc),a0    -buffer
  169.     add.l    (rom_log,pc),a0        +$f80000
  170.     move.l    a0,_privi_addr2
  171.  
  172.     ; find Privilege violation exception code
  173.     lea    (.badrom2,pc),a1
  174.     move.l    (rom_phys,pc),a3
  175.     move.w    #8192/2,d0
  176. .find5    subq.w    #1,d0
  177.     beq    .err
  178.     addq.l    #2,a3
  179.     cmp.l    #$0CAF00F8,(a3)
  180.     bne.b    .find5
  181.     cmp.l    #$0002660C,(6,a3)
  182.     bne.b    .find5
  183.     cmp.l    #$2F7C00F8,(10,a3)
  184.     bne.b    .find5
  185.     cmp.l    #$00024ED5,(16,a3)
  186.     bne.b    .find5
  187.     move.l    a3,d5
  188.  
  189.     ; find Supervisor 010+ code
  190.     move.l    (rom_phys,pc),a3
  191.     move.w    #8192/2,d0
  192. .find6    subq.w    #1,d0
  193.     beq    .err
  194.     addq.l    #2,a3
  195.     cmp.l    #$007C2000,(a3)
  196.     bne.b    .find6
  197.     cmp.l    #$518F40D7,(4,a3)
  198.     bne.b    .find6
  199.     cmp.l    #$2F7C00F8,(8,a3)
  200.     bne.b    .find6
  201.     cmp.l    #$00023F7C,(14,a3)
  202.     bne.b    .find6
  203.     ; inside ram buffer, so generate rom address
  204.     sub.l    (rom_phys,pc),a3    -buffer
  205.     add.l    (rom_log,pc),a3        +$f80000
  206.     move.l    a3,_svptr1
  207.     move.l    a3,_svptr2
  208.  
  209.  
  210.     ; finally ready for patching,
  211.     ; install the patch code
  212.  
  213.     movem.l    (regs,pc),d0/a0
  214.     lea    (_AlertFix_module,pc),a1
  215.     move.l    (installmodule,pc),a3
  216.     jsr    (a3)
  217.  
  218.     ; find ourself
  219.  
  220.     movem.l    (regs,pc),d0/a0
  221.     lea    (_name,pc),a1
  222.     move.l    (findresident,pc),a3
  223.     jsr    (a3)
  224.  
  225.     lea    (.plantfail,pc),a1
  226.     tst.l    d0
  227.     beq    .err
  228.  
  229.     move.l    d0,a5
  230.     ; (RT_INIT,a5) gives us pointer to RT_INIT as logical address,
  231.     ; a5 + RT_SIZE is pointer to data after RT structure (usually
  232.                 ; RT_INIT pos) in physical memory.
  233.     move.l    (RT_INIT,a5),a3
  234.     lea    (RT_SIZE,a5),a5
  235.  
  236.     tst.l    d3
  237.     beq.b    .skip_newalert
  238.  
  239.     btst    #3,($128+1,a6)        AFB_68040 AttnFlags
  240.     beq.b    .no040p_a
  241.  
  242.     ;lea    (_ahook1-_init,a3),a1
  243.     ;move.l    a1,(RT_INIT,a4)
  244.     move.l    a3,(RT_INIT,a4)
  245.  
  246.     lea    (_ahook2-_init,a3),a1
  247.     move.l    d3,a0
  248.     move.w    #$4EB9,(a0)+
  249.     move.l    a1,(a0)+
  250. .no040p_a
  251.     bra.b    .no_newalert
  252. .skip_newalert
  253.     ; okay, we got NewAlert, patch the exception
  254.     ; handler to jump it directly.
  255.     lea    (_newalert-_init,a3),a1
  256.     move.l    d4,a0
  257.     move.w    #$4EB9,(a0)+
  258.     move.l    a1,(a0)+
  259. .no_newalert
  260.  
  261.     btst    #3,($128+1,a6)        AFB_68040 AttnFlags
  262.     beq.b    .no040p_b
  263.  
  264.     lea    (_alert1-_init,a3),a1
  265.     move.w    #$4EB9,(a2)+
  266.     move.l    a1,(a2)+
  267.  
  268.     lea    (_alert2-_init,a3),a1
  269.     addq.l    #6,a2
  270.     move.w    #$4EB9,(a2)+
  271.     move.l    a1,(a2)+
  272.  
  273.     ; find the '$104=ThisTask' write
  274.     lea    (.badrom1,pc),a1
  275.     moveq    #32,d0
  276. .find7    subq.l    #1,d0
  277.     beq.b    .err
  278.     addq.l    #2,a2
  279.     cmp.l    #$2A6E0114,(a2)            'move.l $114(a6),a5'
  280.     bne.b    .find7
  281.     lea    (_alert3-_init,a3),a1
  282.     move.w    #$4EB9,(a2)+
  283.     move.l    a1,(a2)+
  284. .no040p_b
  285.  
  286.     move.l    d5,a0
  287.     lea    (_privi-_init,a3),a1
  288.     move.l    (2,a0),(_privi_addr1-_init,a5)
  289.     move.w    #$4EB9,(a0)+
  290.     move.l    a1,(a0)+
  291.  
  292.     moveq    #1,d7
  293.  
  294. .err    tst.l    d7
  295.     bne.b    .exit
  296.     lea    (.errh,pc),a0
  297.     move.l    a1,-(sp)
  298.     move.l    sp,a1
  299.     move.l    (printf,pc),a2
  300.     jsr    (a2)
  301.     addq.l    #4,sp
  302. .exit    move.l    d7,d0
  303.     rts
  304.  
  305.  
  306. .resname    dc.b    'alert.hook',13,10,0
  307.  
  308. .errh    dc.b    'AlertFix: couldn''t %s!',10,0
  309.  
  310. .no020p    dc.b    'find 68020 or better CPU',0
  311. .nores    dc.b    'find alert.hook',0
  312. .badres    dc.b    'patch alert.hook',0
  313. .badrom1    dc.b    'patch Alert()',0
  314. .badrom2    dc.b    'patch Supervisor()',0
  315. .plantfail    dc.b    'InstallModule(), add some EXTRESBUF',0
  316.  
  317.     CNOP    0,2
  318. _AlertFix_module
  319.  BK_MOD BKMF_SingleMode,_end,(0)<<24+37<<16+NT_UNKNOWN<<8+(256-54),_name,_idstr,_init
  320.  
  321. ; Singlemode on,
  322. ; never init this module, requires KS V37.x or better, module type NT_UNKNOWN, priority -54.
  323.  
  324. _init    ; this code will never be called directly!
  325. _ahook1    moveq    #0,d0
  326.     sub.l    a0,a0
  327.     bsr.b    _write
  328. _backfromh1    EQU    *+2
  329.     jmp    $badc0de
  330.  
  331. _ahook2    moveq    #0,d0
  332.     sub.l    a0,a0
  333.     bsr.b    _write
  334.     moveq    #-1,d0
  335.     rts
  336.  
  337. _alert1    addq.l    #4,(sp)
  338.     sub.l    a0,a0
  339.     bsr.b    _read
  340.     cmp.l    #'HELP',d0
  341.     beq.b    .need_help
  342.     cmp.l    #'HELP',(0).w
  343. .need_help    rts
  344.  
  345. _alert3    move.l    ($114,a6),a5
  346.     bra.b    _alert3b
  347.  
  348. _alert2    addq.l    #6,(sp)
  349.     sub.l    a0,a0
  350.     move.l    #'HELP',d0
  351.     bsr.b    _write
  352.  
  353.     lea    ($100).w,a0
  354.     move.l    d7,d0
  355.     bsr.b    _write
  356.     addq.l    #4,a0
  357. _alert3b    move.l    a5,d0
  358.     ;bra.b    _write            fall thru to _write!
  359.  
  360. ;  IN: a0.l = address
  361. ;      d0.l = data
  362. ; OUT: a0.l = address
  363. _write    movem.l    d1/a1/a5,-(sp)
  364.     lea    (.write,pc),a1
  365.     lea    (runnommu_s,pc),a5
  366. _svptr1    EQU    *+2
  367.     jsr    $badc0de
  368.     movem.l    (sp)+,d1/a1/a5
  369. .write    move.l    d0,(a0)
  370.     rts
  371.  
  372. ;  IN: a0.l = address
  373. ; OUT: a0.l = address
  374. ;      d0.l = data
  375. _read    movem.l    d1/a1/a5,-(sp)
  376.     lea    (.read,pc),a1
  377.     lea    (runnommu_s,pc),a5
  378. _svptr2    EQU    *+2
  379.     jsr    $badc0de
  380.     movem.l    (sp)+,d1/a1/a5
  381.     rts
  382. .read    move.l    (a0),d0
  383.     rts
  384.  
  385. _privi    addq.l    #2,(sp)
  386. _privi_addr1    EQU    *+2
  387.     cmp.l    #$badda7a,(4+2,sp)
  388.     beq.b    .ok
  389. _privi_addr2    EQU    *+2
  390.     cmp.l    #$badda7a,(4+2,sp)
  391.     bne.b    .ok
  392.     move.l    (4+2,sp),(sp)
  393. .ok    rts
  394.  
  395. _newalert    addq.l    #2,(sp)
  396. _newalert_addr    EQU    *+2
  397.     jsr    $badc0de
  398.     tst.b    ($126,a6)
  399.     rts
  400.  
  401.  
  402. ;  IN: a1 = routine to run in supervisor, mmu disabled, end with rts
  403. ;      d0/d2-d7/a0/a2-a4 = whatever you like
  404. ;      a6 = execbase
  405. ; OUT: d1 = scratched
  406. ;      d0/d2-d7/a0/a2-a4 = whatever you like
  407. ;
  408. runnommu_s
  409.     ori.w    #$700,sr
  410.  
  411.     movec    tc,d1
  412.     move.l    d1,-(sp)
  413.     movec    cacr,d1
  414.     move.l    d1,-(sp)
  415.     movec    dtt1,d1
  416.     move.l    d1,-(sp)
  417.     movec    dtt0,d1
  418.     move.l    d1,-(sp)
  419.     movec    itt1,d1
  420.     move.l    d1,-(sp)
  421.     movec    itt0,d1
  422.     move.l    d1,-(sp)
  423.     cpusha    bc            make sure the above is written
  424.     cinva    bc
  425.  
  426.     move.l    #$00FFC000,d1        mark 32-bit: Cacheable, Writethrough
  427.     movec    d1,itt0    
  428.     movec    d1,itt1
  429.     movec    d1,dtt1
  430.     move.l    #$0000C040,d1        mark 24-bit-DMA: Cache-Inhibited, Precise Exception Model
  431.     movec    d1,dtt0
  432.     move.l    #$80008000,d1        instcache + datacache
  433.     movec    d1,cacr
  434.     moveq    #0,d1            turn off possible MMU mapping
  435.     pflusha
  436.     movec    d1,tc
  437.     cpusha    bc
  438.     cinva    bc
  439.  
  440.     jsr    (a1)
  441.  
  442.     cpusha    bc
  443.     move.l    (sp)+,d1
  444.     movec    d1,itt0
  445.     move.l    (sp)+,d1
  446.     movec    d1,itt1
  447.     move.l    (sp)+,d1
  448.     movec    d1,dtt0
  449.     move.l    (sp)+,d1
  450.     movec    d1,dtt1
  451.     move.l    (sp)+,d1
  452.     movec    d1,cacr
  453.     move.l    (sp)+,d1
  454.     pflusha
  455.     movec    d1,tc
  456.     cpusha    bc
  457.     cinva    bc
  458.     nop
  459.     rte
  460.  
  461. _name
  462. _idstr    dc.b    'AlertFix.patchcode',0
  463.  
  464.     CNOP    0,2
  465. _end
  466.  
  467.  
  468.     CNOP    0,2
  469. regs
  470. rom_size    ds.l    1
  471. rom_phys    ds.l    1
  472. rom_log    ds.l    1
  473. findresident    ds.l    1
  474. installmodule    ds.l    1
  475. printf    ds.l    1
  476.  
  477.     SECTION    VERSION,DATA
  478.  
  479.     dc.b    '$VER: AlertFix_PATCH 1.3 (11.9.00)',0
  480.  
  481.